home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 1.iso / desktop / winmaze4.zip / SPIKE.CPP < prev    next >
C/C++ Source or Header  |  1994-05-03  |  11KB  |  354 lines

  1. #include <owl\owlpch.h>
  2. #include <owl\applicat.h>
  3. #include <owl\framewin.h>
  4. #include <owl\dc.h>
  5. #include <string.h>
  6. #include <math.h>
  7. #include <stdlib.h>
  8. #include "plot3d.h"
  9.  
  10. #ifndef TRUE
  11. #define TRUE -1
  12. #endif
  13. #ifndef FALSE
  14. #define FALSE 0
  15. #endif
  16.  
  17. static int    external_to_plot(double,double);
  18. static double f(double,double);
  19. static int    red(double,double);
  20.  
  21. class SpikeWindow : public TFrameWindow
  22.   {
  23.     public:
  24.       SpikeWindow(TWindow* parent, const char far* title);
  25.       void CleanupWindow();
  26.       BOOL IdleAction(long IdleCount);
  27.         // So that the program remains responsive, the plotting is done here.
  28.       void Paint(TDC &dc,BOOL erase,TRect &dirty);
  29.     protected:
  30.       void EvHScroll(UINT code,UINT pos,HWND wnd);
  31.         // Processes a change in the horizontal scroll bar -- a request for
  32.         // a new angle of rotation.
  33.       void EvSize(UINT sizeType,TSize &size);
  34.         // Processes resizing of the window -- a request for a different size
  35.         // plot.
  36.       void EvVScroll(UINT code,UINT pos,HWND wnd);
  37.         // Processes a change in the vertical scroll bar -- a request for a
  38.         // new angle of tilt.
  39.     private:
  40.       double light_x;
  41.       double light_y;
  42.       double light_z;
  43.         // Vector to the major source of light.
  44.       plot3d *plot3d_ptr;
  45.         // Pointer to an instance of the 3D plotting class.
  46.       TRect  region_to_paint;
  47.       int    rotation;
  48.         // The number of degrees the plot is rotated about a line
  49.         // through its center running parallel to the z-axis.
  50.       char   state;
  51.         // State of the plotting; one of the following:
  52.         //     'B' -- beginning
  53.         //     'S' -- preparing plot
  54.         //     'P' -- plotting
  55.         //     'F' -- failure
  56.         //     'D' -- done
  57.       int    tilt;
  58.         // The number of degrees the plot is tilted towards the viewer.
  59.   
  60.       DECLARE_RESPONSE_TABLE(SpikeWindow);
  61.        // Associates user commands with methods in this program.
  62.   };
  63.  
  64. DEFINE_RESPONSE_TABLE1(SpikeWindow,TFrameWindow)
  65.   EV_WM_HSCROLL,
  66.   EV_WM_VSCROLL,
  67.   EV_WM_SIZE,
  68. END_RESPONSE_TABLE;
  69.  
  70. SpikeWindow::SpikeWindow(
  71.   TWindow        *parent,
  72.   const char far *title) : TFrameWindow(parent,title)
  73.     {
  74.       Attr.Style |= WS_VSCROLL | WS_HSCROLL;
  75.         // Scroll bars are used to specify tilt and rotation.
  76.       AssignMenu("SPIKE_MENU");
  77.       state='B';             // beginning plot
  78.       rotation=0;            // (degrees)
  79.       tilt=30;               // (degrees)
  80.       light_x=(double) 1.0;  // vector to light source
  81.       light_y=(double) -1.0;
  82.       light_z=(double) 1.0;
  83.       plot3d_ptr=new plot3d((TFrameWindow *) this);
  84.     }
  85.  
  86. void SpikeWindow::CleanupWindow()
  87.   {
  88.     delete plot3d_ptr; // destroy 3D plotter
  89.     TFrameWindow::CleanupWindow();
  90.   }
  91.  
  92. BOOL SpikeWindow::IdleAction(long IdleCount)
  93. // So that the program remains responsive, the plotting is done here.
  94.   {
  95.     switch (state)
  96.       // State of the plotting; one of the following:
  97.       //     'B' -- beginning
  98.       //     'S' -- preparing plot
  99.       //     'P' -- plotting
  100.       //     'F' -- failure
  101.       //     'D' -- done
  102.       {
  103.         case 'B': // begin
  104.           GetClientRect(region_to_paint);
  105.             // The whole plot is being done.
  106.           SetScrollRange(SB_VERT,0,90);   
  107.             // The plot may be tilted between 0 and 90 degrees.
  108.           SetScrollRange(SB_HORZ,0,360);
  109.             // The plot may be rotated between 0 and 360 degrees.
  110.           SetScrollPos(SB_VERT,90-tilt);
  111.             // Display the current tilt on the vertical scroll bar.
  112.           SetScrollPos(SB_HORZ,rotation);
  113.             // Display the current rotation on the horizontal scroll bar.
  114.           if (IsIconic())
  115.             state='F';
  116.           else
  117.             state='S';
  118.           break;
  119.         case 'S': // prepare plot
  120.           switch (plot3d_ptr->prepare_plot(
  121.            f,                        // function f(x,y) to be plotted
  122.            -1.0,                     // minimum x
  123.            1.0,                      // maximum x
  124.            -1.0,                     // minimum y
  125.            1.0,                      // maximum y
  126.            external_to_plot,         // don't plot -- always FALSE
  127.            red,                      // highlight -- always FALSE
  128.            120,                      // number of x divisions
  129.            120,                      // number of y divisions
  130.            double(rotation),         // rotation in degrees
  131.            double(tilt),             // tilt in degrees
  132.            light_x,light_y,light_z)) // vector to light source
  133.             {
  134.               case 'S': // success; plot prepared
  135.                 state='P'; // proceed to plot
  136.                 break;
  137.               case 'F': // failure (already announced in pop up)
  138.                 state='F';
  139.                 break;
  140.               default:  // continue
  141.                 break;
  142.             }
  143.           break;
  144.         case 'P': // plotting
  145.           switch (plot3d_ptr->plot(
  146.            region_to_paint,
  147.            FALSE,                     // highlight flagged areas
  148.            FALSE,                     // only plot flagged areas
  149.            1.0))                      // contrast adjustment
  150.             {
  151.               case 'S': // success; plot complete
  152.                 state='D'; // proceed to wait for user input
  153.                 break;
  154.               case 'F': // failure (already announced in pop up)
  155.                 {
  156.                   state='F';
  157.                   TClientDC *dc=new TClientDC(*this);
  158.                   delete dc;
  159.                 }
  160.                 break;
  161.               default:  // continue
  162.                 break;
  163.             }
  164.           break;
  165.         case 'F': // failed; wait for user input
  166.           break;
  167.         default:  // done; wait for user input
  168.           break;
  169.       }
  170.     TFrameWindow::IdleAction(IdleCount);
  171.     return TRUE;
  172.   }
  173.  
  174. void SpikeWindow::Paint(TDC &dc,BOOL erase,TRect &dirty)
  175. // This method is invoked when part of the display has been made "dirty"
  176. // (for example, when another window has been moved from atop the display).
  177.   {
  178.      switch (state)
  179.        {
  180.          case 'B': // beginning
  181.              // Nothing is displayed yet; nothing need be restored.
  182.            break;
  183.          case 'S': // preparing plot
  184.            dc.PatBlt(this->GetClientRect(),WHITENESS);
  185.            dc.TextOut(0,0,"Preparing plot...");
  186.              // The internal state of the 3D plotter is not available here,
  187.              // so display this message.
  188.            break;
  189.          case 'P': // still plotting
  190.            state='P';
  191.            GetClientRect(region_to_paint);
  192.            plot3d_ptr->restart_plot();
  193.              // Proceed to restore the entire display.  Because the painter's
  194.              // algorithm is used, areas outside the "dirty" region may still
  195.              // need plotting.
  196.            break;
  197.          case 'F': // failed
  198.              // Nothing is being displayed; nothing need be restored.
  199.            break;
  200.          default:  // done
  201.            state='P';
  202.            region_to_paint=dirty;
  203.            plot3d_ptr->restart_plot();
  204.              // Redo the "dirty" region.
  205.            break;
  206.        }
  207.   }
  208.  
  209. void SpikeWindow::EvHScroll(UINT code,UINT pos,HWND wnd)
  210. // Processes a change in the horizontal scroll bar -- a request for a new angle
  211. // of rotation.
  212.   {
  213.     TFrameWindow::EvHScroll(code,pos,wnd);
  214.     int change=FALSE;
  215.     switch (code) 
  216.       {
  217.         case SB_LINEUP:
  218.           rotation--;
  219.           change=TRUE;
  220.           break;
  221.         case SB_LINEDOWN:
  222.           rotation++;
  223.           change=TRUE;
  224.           break;
  225.         case SB_PAGEUP:
  226.           rotation-=10;
  227.           change=TRUE;
  228.           break;
  229.         case SB_PAGEDOWN:
  230.           rotation+=10;
  231.           change=TRUE;
  232.           break;
  233.         case SB_THUMBPOSITION:
  234.           rotation=pos;
  235.           change=TRUE;
  236.           break;
  237.         case SB_THUMBTRACK:
  238.           break;
  239.         default:
  240.           break;
  241.       }
  242.     if (change)
  243.       {
  244.         delete plot3d_ptr;
  245.         state='B'; // proceed to completely redo plot
  246.         plot3d_ptr=new plot3d((TFrameWindow *) this);
  247.       }
  248.     return;
  249.   }
  250.  
  251. void SpikeWindow::EvSize(UINT sizeType,TSize &size)
  252. // Processes resizing of the window -- a request for a different size plot.
  253.   {
  254.     delete plot3d_ptr;  // get rid of old 3D plotter
  255.     state='B';          // proceed to completely redo plot
  256.     plot3d_ptr=new plot3d((TFrameWindow *) this);
  257.     return;
  258.   }
  259.  
  260. void SpikeWindow::EvVScroll(UINT code,UINT pos,HWND wnd)
  261. // Processes a change in the vertical scroll bar -- a request for a new angle of
  262. // tilt.
  263.   {
  264.     TFrameWindow::EvVScroll(code,pos,wnd);
  265.     int change=FALSE;
  266.     switch (code) 
  267.       {
  268.         case SB_LINEUP:
  269.           tilt++;
  270.           if (tilt > 90)
  271.             tilt=90;
  272.           change=TRUE;
  273.           break;
  274.         case SB_LINEDOWN:
  275.           tilt--;
  276.           if (tilt < 0)
  277.             tilt=0;
  278.           change=TRUE;
  279.           break;
  280.         case SB_PAGEUP:
  281.           tilt+=5;
  282.           if (tilt > 90)
  283.             tilt=90;
  284.           change=TRUE;
  285.           break;
  286.         case SB_PAGEDOWN:
  287.           tilt-=5;
  288.           if (tilt < 0)
  289.             tilt=0;
  290.           change=TRUE;
  291.           break;
  292.         case SB_THUMBPOSITION:
  293.           tilt=90-pos;
  294.           change=TRUE;
  295.           break;
  296.         case SB_THUMBTRACK:
  297.           break;
  298.         default:
  299.           break;
  300.       }
  301.     if (change)
  302.       {
  303.         delete plot3d_ptr;
  304.         state='B'; // proceed to completely redo plot
  305.         plot3d_ptr=new plot3d((TFrameWindow *) this);
  306.       }
  307.     return;
  308.   }
  309.  
  310. static int external_to_plot(
  311.   double x,
  312.   double y)
  313. // Returns TRUE if and only if a point (x,y) is external to the plot.
  314.     {
  315.        return FALSE;
  316.     }
  317.  
  318. static int red(
  319.   double x,
  320.   double y)
  321. // Returns TRUE if and only if a point (x,y) is flagged to be highlighted.
  322.     {
  323.        return FALSE;
  324.     }
  325.  
  326. static double f(
  327.   double x,
  328.   double y)
  329. // The function to be plotted.
  330.     {
  331.        double t1=x*x+y*y;
  332.        double t2=cos(7.0*sqrt(t1));
  333.        return 2.0*t2*t2/(1.0+30.0*t1);
  334.     }
  335.  
  336. class SpikeApp : public TApplication
  337.   {
  338.     public:
  339.            SpikeApp() : TApplication("Spike") {}
  340.       void InitMainWindow();
  341.   };
  342.  
  343. void SpikeApp::InitMainWindow()
  344.   {
  345.     MainWindow=new SpikeWindow(0,"Spike");
  346.     MainWindow->SetIcon(this,"SPIKE_ICON");
  347.   }
  348.  
  349. int OwlMain(int /*argc*/, char* /*argv*/ [])
  350. // Execution of this program starts here.
  351.   {
  352.     return SpikeApp().Run(); // Process windows messages until user is done.
  353.   }
  354.